#pragma semicolon 1
#include <sourcemod>
#include <sdktools>

#define PLUGIN_VERSION "1.5.0"


new Float:JumpTime[MAXPLAYERS+1];
new bool:JumpEnabled[MAXPLAYERS+1];
new bool:Jumped[MAXPLAYERS+1];
new Buffer[MAXPLAYERS+1];
 
 
new Handle:timer_handle=INVALID_HANDLE;
new Handle:Enabled = INVALID_HANDLE;
new Handle:InitEnabled = INVALID_HANDLE;

new Handle:CVarDamage = INVALID_HANDLE;
new Handle:CVarxymult = INVALID_HANDLE;
new Handle:CVarzmult = INVALID_HANDLE;
new Handle:CVarDamage2 = INVALID_HANDLE;
new Handle:CVarxymult2 = INVALID_HANDLE;
new Handle:CVarzmult2 = INVALID_HANDLE;
 
//new Handle:CVarTick = INVALID_HANDLE;
new Handle:CVarMsgTime = INVALID_HANDLE;
 

			new g_iVelocity;
			new all_iVelocity;


public Plugin:myinfo = 
{
	name = "轻功插件",
	author = "小海",
	description = "轻功插件",
	version = PLUGIN_VERSION,	
}
	new Float:zmult;
	new Float:xymult;
	new Float:zmult2;
	new Float:xymult2;
	new time;
	//new difficult;
	new Float:velocity[3];
	new bool:suppermode=false;

	new damage;
	new damage2;

	new SupperKey=IN_DUCK;
	new DisableKey=IN_SPEED;

public OnPluginStart()
{
	CreateConVar("l4d_incappedpillspop_version", PLUGIN_VERSION, "轻功版本", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_NOTIFY|FCVAR_DONTRECORD);
	
	Enabled = CreateConVar("l4d_jump_enabled", "1", " 1 : 启动轻功 , 0: 禁用轻功 ", FCVAR_PLUGIN);
	InitEnabled = CreateConVar("l4d_jump_init", "1", " 1 : 初始启动 , 0: 初始禁用 ", FCVAR_PLUGIN);
	CVarzmult = CreateConVar("l4d_jump_zmult", "2.5", "垂直加速", FCVAR_PLUGIN);
	CVarxymult = CreateConVar("l4d_jump_xymult", "2.6", "水平加速", FCVAR_PLUGIN);
	CVarzmult2 = CreateConVar("l4d_jump_zmult2", "2.5", "超级轻功垂直加速", FCVAR_PLUGIN);
	CVarxymult2 = CreateConVar("l4d_jump_xymult2", "2.6", "超级轻功水平加速", FCVAR_PLUGIN);
	//CVarTick = CreateConVar("l4d_jump_difficult", "9999.0", "使用轻功难易度， 越小越难 单位 秒", FCVAR_PLUGIN);
	CVarMsgTime = CreateConVar("l4d_jump_showtime", "200", "提示间隔", FCVAR_PLUGIN);
 	
	AutoExecConfig(true, "l4d_jump_v13");

	HookConVarChange(CVarzmult, ConVarChange);
	HookConVarChange(CVarxymult, ConVarChange);
	HookConVarChange(CVarzmult2, ConVarChange);
	HookConVarChange(CVarxymult2, ConVarChange);
	//HookConVarChange(CVarTick, ConVarChange);

	zmult=GetConVarFloat(CVarzmult );
	xymult=GetConVarFloat(CVarxymult );
	zmult2=GetConVarFloat(CVarzmult2 );
	xymult2=GetConVarFloat(CVarxymult2 );
	//difficult=GetConVarFloat(CVarTick);
 	
	g_iVelocity = FindSendPropOffs("CBasePlayer", "m_vecVelocity[0]");
	all_iVelocity = FindSendPropOffs("CBasePlayer", "m_vecVelocity[0]");
    	
	HookEvent("round_end", RoundEnd);
	HookEvent("mission_lost", RoundEnd);
	HookEvent("finale_win", RoundEnd);
 	
	HookEvent("round_start", RoundStart);
	HookEvent("player_jump", player_jump);
	 
	Reset();
}
public ConVarChange(Handle:convar, const String:oldValue[], const String:newValue[])
{
	zmult=GetConVarFloat(CVarzmult );
	xymult=GetConVarFloat(CVarxymult );
	zmult2=GetConVarFloat(CVarzmult2 );
	xymult2=GetConVarFloat(CVarxymult2 );
	//difficult=GetConVarFloat(CVarTick);
}

 
public Action:Msg(Handle:timer, any:data)
{
	PrintToChatAll("\x04按两下空格使用轻功,按E+空格使用超级轻功");
  	return Plugin_Continue;
}
public Action:player_jump(Handle:hEvent, const String:name[], bool:dontBroadcast)
{

	if(GetConVarInt(Enabled)==0)return;
	new client = GetClientOfUserId(GetEventInt(hEvent, "userid"));
	if (!client) return;
	if (!IsClientInGame(client)) return;
	//if (GetClientTeam(client)!=2) return;
	if (!IsPlayerAlive(client)) return;

 	new buttons = GetClientButtons(client);
	if( (buttons & DisableKey))
	{
		return;
	}
	Buffer[client]=0;
	JumpTime[client]=GetEngineTime() ;

	Jumped[client]=true;
	//PrintToChat(client, "jump t %f",JumpTime[client]);
	return;
 }
new Float:duration=0;
new buttons;
public OnGameFrame()
{
	if(GetConVarInt(Enabled)==0)return;
	time=GetEngineTime();
  	for (new client = 1; client <= MaxClients; client++)
	{
		if (JumpEnabled[client] && Jumped[client] && IsClientInGame(client) && IsPlayerAlive(client))
		{
			duration=FloatSub(time,JumpTime[client]);
			buttons = GetClientButtons(client);

 			if( (buttons & IN_JUMP)  )
			{
				if(Buffer[client]>1)
				{
					//sPrintToChat(client, "%f %f %f", time, duration, difficult);
					suppermode=false;
					if((buttons & SupperKey) || (buttons & IN_USE))
					{
						suppermode=true;
					}
 				
					GetEntDataVector(client, all_iVelocity, velocity);
					if(	velocity[2] >0)
					{
						if  (suppermode)
						{
							velocity[0]=velocity[0]*xymult2;
							velocity[1]=velocity[1]*xymult2;
							velocity[2]=velocity[2]*zmult2;
						}
						else
						{
							velocity[0]=velocity[0]*xymult;
							velocity[1]=velocity[1]*xymult;
							velocity[2]=velocity[2]*zmult;
						}
						TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, velocity);
						SetEntDataVector(client, all_iVelocity, velocity);
						Jumped[client]=false;
						JumpTime[client]=0;
						
						if(suppermode)
						{
							PrintCenterText(client, "超级轻功");
						}
						else
						{
							PrintCenterText(client, "轻功");
						}
 					}
					else
					{
						Jumped[client]=false;
					}
					
				}
 			}
			else
			{
				Buffer[client]++;
			}
			//new cl_flags;

			//GetEntDataVector(client,g_iVelocity,speed);
			//cl_flags = GetEntityFlags(client);
			//if(speed[2] >= 0 || (cl_flags & FL_ONGROUND)) 
			//{
  	//			Jumped[client]=0;
			//	timepasted[client]=0;
			//}
		}
	}
	return;
}
 
 stock DamageEffect(target, String:demage[])
{
	new String:N[20];
	Format(N, 20, "target%d", target);
	new pointHurt = CreateEntityByName("point_hurt");			// Create point_hurt
	DispatchKeyValue(target, "targetname", N);			// mark target
	DispatchKeyValue(pointHurt, "Damage", demage);					// No Damage, just HUD display. Does stop Reviving though
	DispatchKeyValue(pointHurt, "DamageTarget", N);		// Target Assignment
	DispatchKeyValue(pointHurt, "DamageType", "65536");			// Type of damage
	DispatchSpawn(pointHurt);									// Spawn descriped point_hurt
	AcceptEntityInput(pointHurt, "Hurt"); 						// Trigger point_hurt execute
	AcceptEntityInput(pointHurt, "Kill"); 						// Remove point_hurt
	//DispatchKeyValue(target, "targetname",	"cake");			// Clear target's mark
}
 

public Action:RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
 	if(timer_handle != INVALID_HANDLE )
	 {
		KillTimer(timer_handle);
		timer_handle=INVALID_HANDLE;
	}

	return Plugin_Continue;
}

public Action:RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
	 
	if(timer_handle != INVALID_HANDLE )
	{
		KillTimer(timer_handle);
		timer_handle=INVALID_HANDLE;
	}
	if(timer_handle == INVALID_HANDLE)
	{
		timer_handle=CreateTimer(GetConVarFloat(CVarMsgTime), Msg, 0, TIMER_REPEAT);
	}
	return Plugin_Continue;
}
 
stock CheatCommand(client, String:command[], String:parameter1[], String:parameter2[])
{
	new userflags = GetUserFlagBits(client);
	SetUserFlagBits(client, ADMFLAG_ROOT);
	new flags = GetCommandFlags(command);
	SetCommandFlags(command, flags & ~FCVAR_CHEAT);
	FakeClientCommand(client, "%s %s %s", command, parameter1, parameter2);
	SetCommandFlags(command, flags);
	SetUserFlagBits(client, userflags);
}
 
Reset()
{
	new bool:e=GetConVarInt(InitEnabled)>0;
	for (new x = 0; x < MAXPLAYERS+1; x++)
	{
 			JumpEnabled[x]=e;
	}
}